﻿2026-05-16T06:02:06.5418808Z ##[group]Run pnpm verify:phase-4
2026-05-16T06:02:06.5419163Z [36;1mpnpm verify:phase-4[0m
2026-05-16T06:02:06.5454909Z shell: /usr/bin/bash -e {0}
2026-05-16T06:02:06.5455175Z env:
2026-05-16T06:02:06.5455445Z   PNPM_HOME: /home/runner/setup-pnpm/node_modules/.bin
2026-05-16T06:02:06.5455782Z   SKIP_PHASE_3_CARRYOVER: 1
2026-05-16T06:02:06.5456036Z   SKIP_TRACE_CHECK: 1
2026-05-16T06:02:06.5456255Z ##[endgroup]
2026-05-16T06:02:06.8336863Z 
2026-05-16T06:02:06.8337924Z > rebno@0.0.0 verify:phase-4 /home/runner/work/rebno/rebno
2026-05-16T06:02:06.8338962Z > node scripts/verify-phase-4.mjs
2026-05-16T06:02:06.8339415Z 
2026-05-16T06:02:06.8661007Z 
2026-05-16T06:02:06.8661610Z === Workspace: typecheck ===
2026-05-16T06:02:06.8662641Z >>> pnpm -r typecheck
2026-05-16T06:02:07.2138300Z Scope: 5 of 6 workspace projects
2026-05-16T06:02:07.2192305Z packages/db typecheck$ tsc --noEmit
2026-05-16T06:02:07.2200795Z packages/game-logic typecheck$ tsc --noEmit
2026-05-16T06:02:09.7008096Z packages/game-logic typecheck: Done
2026-05-16T06:02:09.7038635Z packages/protocol typecheck$ tsc --noEmit
2026-05-16T06:02:11.6783616Z packages/db typecheck: Done
2026-05-16T06:02:13.0483889Z packages/protocol typecheck: Done
2026-05-16T06:02:13.0491276Z apps/server typecheck$ tsc --noEmit
2026-05-16T06:02:13.0494392Z apps/client typecheck$ tsc --noEmit
2026-05-16T06:02:25.1373198Z apps/client typecheck: Done
2026-05-16T06:02:25.4878907Z apps/server typecheck: Done
2026-05-16T06:02:25.4989624Z 
2026-05-16T06:02:25.4990397Z === Lint: protocol-sync ===
2026-05-16T06:02:25.4991172Z >>> pnpm lint:protocol-sync
2026-05-16T06:02:25.8064895Z 
2026-05-16T06:02:25.8066041Z > rebno@0.0.0 lint:protocol-sync /home/runner/work/rebno/rebno
2026-05-16T06:02:25.8067360Z > node tools/scripts/lint-protocol-sync.mjs
2026-05-16T06:02:25.8067974Z 
2026-05-16T06:02:25.8387550Z lint-protocol-sync: OK
2026-05-16T06:02:25.8514830Z 
2026-05-16T06:02:25.8515654Z === Lint: game-logic-purity ===
2026-05-16T06:02:25.8516474Z >>> pnpm lint:game-logic-purity
2026-05-16T06:02:26.1495363Z 
2026-05-16T06:02:26.1496441Z > rebno@0.0.0 lint:game-logic-purity /home/runner/work/rebno/rebno
2026-05-16T06:02:26.1497741Z > node tools/scripts/lint-game-logic-purity.mjs
2026-05-16T06:02:26.1498356Z 
2026-05-16T06:02:26.1837862Z lint-game-logic-purity: OK (8 file(s) clean)
2026-05-16T06:02:26.1964711Z 
2026-05-16T06:02:26.1965522Z === Lint: better-auth-schema-sync ===
2026-05-16T06:02:26.1966327Z >>> pnpm lint:better-auth-schema-sync
2026-05-16T06:02:26.4907901Z 
2026-05-16T06:02:26.4909036Z > rebno@0.0.0 lint:better-auth-schema-sync /home/runner/work/rebno/rebno
2026-05-16T06:02:26.4910352Z > node tools/scripts/lint-better-auth-schema-sync.mjs
2026-05-16T06:02:26.4910920Z 
2026-05-16T06:02:28.1166855Z lint-better-auth-schema-sync: OK
2026-05-16T06:02:28.1295047Z 
2026-05-16T06:02:28.1295815Z === Lint: rate-limit-budgets ===
2026-05-16T06:02:28.1296594Z >>> pnpm lint:rate-limit-budgets
2026-05-16T06:02:28.4245917Z 
2026-05-16T06:02:28.4247040Z > rebno@0.0.0 lint:rate-limit-budgets /home/runner/work/rebno/rebno
2026-05-16T06:02:28.4248247Z > node tools/scripts/lint-rate-limit-budgets.mjs
2026-05-16T06:02:28.4248886Z 
2026-05-16T06:02:28.4558570Z lint-rate-limit-budgets: OK (5 D-22 budgets locked)
2026-05-16T06:02:28.4680940Z 
2026-05-16T06:02:28.4681635Z === Lint: no-clipboard-rce ===
2026-05-16T06:02:28.4683037Z >>> pnpm lint:no-clipboard-rce
2026-05-16T06:02:28.7577011Z 
2026-05-16T06:02:28.7578208Z > rebno@0.0.0 lint:no-clipboard-rce /home/runner/work/rebno/rebno
2026-05-16T06:02:28.7579353Z > node tools/scripts/lint-no-clipboard-rce.mjs
2026-05-16T06:02:28.7579977Z 
2026-05-16T06:02:28.7939852Z lint-no-clipboard-rce: OK (22 file(s) clean)
2026-05-16T06:02:28.8071325Z 
2026-05-16T06:02:28.8072289Z === Lint: room-layout ===
2026-05-16T06:02:28.8073057Z >>> pnpm lint:room-layout
2026-05-16T06:02:29.0957967Z 
2026-05-16T06:02:29.0959128Z > rebno@0.0.0 lint:room-layout /home/runner/work/rebno/rebno
2026-05-16T06:02:29.0960427Z > node tools/scripts/lint-room-layout.mjs
2026-05-16T06:02:29.0961655Z 
2026-05-16T06:02:29.1327969Z lint-room-layout: OK
2026-05-16T06:02:29.1455211Z 
2026-05-16T06:02:29.1455987Z === ADR 0004 lint ===
2026-05-16T06:02:29.1456859Z >>> pnpm lint:adr:0004
2026-05-16T06:02:29.4389665Z 
2026-05-16T06:02:29.4390768Z > rebno@0.0.0 lint:adr:0004 /home/runner/work/rebno/rebno
2026-05-16T06:02:29.4392611Z > node tools/asset-catalog/scripts/lint-adr.mjs docs/adr/0004-room-hot-reload.md --no-matrix
2026-05-16T06:02:29.4393617Z 
2026-05-16T06:02:29.4703425Z OK: ADR docs/adr/0004-room-hot-reload.md validated (no-matrix mode — Michael Nygard sections present)
2026-05-16T06:02:29.4829739Z 
2026-05-16T06:02:29.4830541Z === Drizzle: emit-check ===
2026-05-16T06:02:29.4831326Z >>> pnpm db:emit-check
2026-05-16T06:02:29.7715624Z 
2026-05-16T06:02:29.7716811Z > rebno@0.0.0 db:emit-check /home/runner/work/rebno/rebno
2026-05-16T06:02:29.7719629Z > pnpm -C packages/db exec drizzle-kit generate && node -e "require('fs').copyFileSync('packages/db/migrations/0001_baseline.sql','docs/extracted-server/0001_baseline.sql')" && git diff --exit-code packages/db/migrations/0001_baseline.sql docs/extracted-server/0001_baseline.sql
2026-05-16T06:02:29.7721606Z 
2026-05-16T06:02:30.2091533Z No config path provided, using default 'drizzle.config.ts'
2026-05-16T06:02:30.2096316Z Reading config file '/home/runner/work/rebno/rebno/packages/db/drizzle.config.ts'
2026-05-16T06:02:30.6345381Z 8 tables
2026-05-16T06:02:30.6346123Z accounts 8 columns 1 indexes 0 fks
2026-05-16T06:02:30.6346974Z audit_log 6 columns 0 indexes 2 fks
2026-05-16T06:02:30.6350314Z characters 9 columns 0 indexes 1 fks
2026-05-16T06:02:30.6351148Z inventory_items 4 columns 0 indexes 1 fks
2026-05-16T06:02:30.6352284Z legacy_credentials_staging 6 columns 0 indexes 0 fks
2026-05-16T06:02:30.6353195Z message_board_replies 5 columns 0 indexes 2 fks
2026-05-16T06:02:30.6354030Z message_board_topics 7 columns 0 indexes 1 fks
2026-05-16T06:02:30.6354769Z sessions 5 columns 0 indexes 1 fks
2026-05-16T06:02:30.6355251Z 
2026-05-16T06:02:30.6356110Z No schema changes, nothing to migrate 😴
2026-05-16T06:02:31.2942485Z 
2026-05-16T06:02:31.2943360Z === Drizzle: schema-sync ===
2026-05-16T06:02:31.2944142Z >>> pnpm lint:schema-sync
2026-05-16T06:02:31.5850940Z 
2026-05-16T06:02:31.5852297Z > rebno@0.0.0 lint:schema-sync /home/runner/work/rebno/rebno
2026-05-16T06:02:31.5855708Z > node -e "const a=require('fs').readFileSync('packages/db/migrations/0001_baseline.sql');const b=require('fs').readFileSync('docs/extracted-server/0001_baseline.sql');if(Buffer.compare(a,b)!==0){console.error('docs/extracted-server/0001_baseline.sql out of sync with packages/db/migrations/0001_baseline.sql');process.exit(1)}console.log('OK')"
2026-05-16T06:02:31.5858140Z 
2026-05-16T06:02:31.6128504Z OK
2026-05-16T06:02:31.6270610Z 
2026-05-16T06:02:31.6271386Z === Drizzle: source-comments ===
2026-05-16T06:02:31.6272506Z >>> pnpm lint:source-comments
2026-05-16T06:02:31.9450163Z 
2026-05-16T06:02:31.9451265Z > rebno@0.0.0 lint:source-comments /home/runner/work/rebno/rebno
2026-05-16T06:02:31.9452714Z > pnpm -C packages/db run lint:source-comments
2026-05-16T06:02:31.9453347Z 
2026-05-16T06:02:32.2403905Z 
2026-05-16T06:02:32.2405156Z > @rebno/db@0.1.0 lint:source-comments /home/runner/work/rebno/rebno/packages/db
2026-05-16T06:02:32.2406343Z > node scripts/check-source-comments.mjs
2026-05-16T06:02:32.2406965Z 
2026-05-16T06:02:32.2799398Z check-source-comments: OK (50 columns, all SOURCE-cited)
2026-05-16T06:02:32.3031720Z 
2026-05-16T06:02:32.3034740Z === Workspace: test ===
2026-05-16T06:02:32.3035451Z >>> pnpm -r test
2026-05-16T06:02:32.6029638Z Scope: 5 of 6 workspace projects
2026-05-16T06:02:32.6084275Z packages/db test$ vitest run
2026-05-16T06:02:32.6092761Z packages/game-logic test$ vitest run
2026-05-16T06:02:33.1064541Z packages/db test: [1m[30m[46m RUN [49m[39m[22m [36mv4.1.5 [39m[90m/home/runner/work/rebno/rebno/packages/db[39m
2026-05-16T06:02:33.1083755Z packages/game-logic test: [1m[30m[46m RUN [49m[39m[22m [36mv4.1.5 [39m[90m/home/runner/work/rebno/rebno/packages/game-logic[39m
2026-05-16T06:02:33.5424566Z packages/game-logic test:  [32m✓[39m test/step-bno-fidelity.test.ts [2m([22m[2m13 tests[22m[2m)[22m[32m 15[2mms[22m[39m
2026-05-16T06:02:33.7557986Z packages/game-logic test:  [32m✓[39m test/collision-axis-slide.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m 7[2mms[22m[39m
2026-05-16T06:02:33.9646365Z packages/game-logic test:  [32m✓[39m test/wall-slide.test.ts [2m([22m[2m1 test[22m[2m)[22m[32m 5[2mms[22m[39m
2026-05-16T06:02:34.1104128Z packages/db test:  [32m✓[39m tests/promotion.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 8[2mms[22m[39m
2026-05-16T06:02:34.2214987Z packages/game-logic test:  [32m✓[39m test/golden.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m 10[2mms[22m[39m
2026-05-16T06:02:34.3266974Z packages/db test:  [32m✓[39m tests/save-format-traceability.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 8[2mms[22m[39m
2026-05-16T06:02:34.4479296Z packages/game-logic test:  [32m✓[39m test/walkable-edge.test.ts [2m([22m[2m1 test[22m[2m)[22m[32m 5[2mms[22m[39m
2026-05-16T06:02:34.6662143Z packages/game-logic test:  [32m✓[39m test/movement-constants.test.ts [2m([22m[2m9 tests[22m[2m)[22m[32m 7[2mms[22m[39m
2026-05-16T06:02:34.8908897Z packages/game-logic test:  [32m✓[39m test/sprite-state-machine.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 7[2mms[22m[39m
2026-05-16T06:02:35.1028594Z packages/db test:  [32m✓[39m tests/schema-shape.test.ts [2m([22m[2m10 tests[22m[2m)[22m[32m 12[2mms[22m[39m
2026-05-16T06:02:35.1123028Z packages/game-logic test:  [32m✓[39m test/navi-mask-bbox.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m 6[2mms[22m[39m
2026-05-16T06:02:35.1126502Z packages/db test: [2m Test Files [22m [1m[32m3 passed[39m[22m[90m (3)[39m
2026-05-16T06:02:35.1127855Z packages/db test: [2m      Tests [22m [1m[32m22 passed[39m[22m[90m (22)[39m
2026-05-16T06:02:35.1128959Z packages/db test: [2m   Start at [22m 06:02:33
2026-05-16T06:02:35.1130869Z packages/db test: [2m   Duration [22m 2.00s[2m (transform 159ms, setup 0ms, import 1.40s, tests 27ms, environment 0ms)[22m
2026-05-16T06:02:35.1446013Z packages/db test: Done
2026-05-16T06:02:35.1462753Z packages/protocol test$ vitest run
2026-05-16T06:02:35.3512079Z packages/game-logic test:  [32m✓[39m test/platform-cycle.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 14[2mms[22m[39m
2026-05-16T06:02:35.5920330Z packages/game-logic test:  [32m✓[39m test/accumulator.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 7[2mms[22m[39m
2026-05-16T06:02:35.6713129Z packages/protocol test: [1m[30m[46m RUN [49m[39m[22m [36mv4.1.5 [39m[90m/home/runner/work/rebno/rebno/packages/protocol[39m
2026-05-16T06:02:35.8091722Z packages/game-logic test:  [32m✓[39m test/run-speed.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 6[2mms[22m[39m
2026-05-16T06:02:36.0826414Z packages/game-logic test:  [32m✓[39m test/rng.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 8[2mms[22m[39m
2026-05-16T06:02:36.0893901Z packages/protocol test:  [32m✓[39m test/codec.test.ts [2m([22m[2m18 tests[22m[2m)[22m[32m 22[2mms[22m[39m
2026-05-16T06:02:36.0930151Z packages/game-logic test: [2m Test Files [22m [1m[32m12 passed[39m[22m[90m (12)[39m
2026-05-16T06:02:36.0933072Z packages/game-logic test: [2m      Tests [22m [1m[32m61 passed[39m[22m[90m (61)[39m
2026-05-16T06:02:36.0953152Z packages/game-logic test: [2m   Start at [22m 06:02:33
2026-05-16T06:02:36.0969244Z packages/game-logic test: [2m   Duration [22m 2.97s[2m (transform 267ms, setup 0ms, import 510ms, tests 98ms, environment 2ms)[22m
2026-05-16T06:02:36.1357724Z packages/game-logic test: Done
2026-05-16T06:02:36.2790511Z packages/protocol test:  [32m✓[39m test/intents.test.ts [2m([22m[2m10 tests[22m[2m)[22m[32m 9[2mms[22m[39m
2026-05-16T06:02:36.4486335Z packages/protocol test:  [32m✓[39m test/state.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 6[2mms[22m[39m
2026-05-16T06:02:36.6055623Z packages/protocol test:  [32m✓[39m test/schema-shape.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 5[2mms[22m[39m
2026-05-16T06:02:36.6099857Z packages/protocol test: [2m Test Files [22m [1m[32m4 passed[39m[22m[90m (4)[39m
2026-05-16T06:02:36.6119274Z packages/protocol test: [2m      Tests [22m [1m[32m36 passed[39m[22m[90m (36)[39m
2026-05-16T06:02:36.6125480Z packages/protocol test: [2m   Start at [22m 06:02:35
2026-05-16T06:02:36.6127373Z packages/protocol test: [2m   Duration [22m 928ms[2m (transform 145ms, setup 0ms, import 282ms, tests 42ms, environment 0ms)[22m
2026-05-16T06:02:36.6439829Z packages/protocol test: Done
2026-05-16T06:02:36.6447259Z apps/client test$ vitest run --exclude 'test/e2e/**'
2026-05-16T06:02:36.6450620Z apps/server test$ vitest run --exclude 'test/**/*.integ.test.ts'
2026-05-16T06:02:37.1831027Z apps/server test: [1m[30m[46m RUN [49m[39m[22m [36mv4.1.5 [39m[90m/home/runner/work/rebno/rebno/apps/server[39m
2026-05-16T06:02:37.2423935Z apps/client test: [1m[46m RUN [49m[22m [36mv3.2.4 [39m[90m/home/runner/work/rebno/rebno/apps/client[39m
2026-05-16T06:02:37.6946154Z apps/server test:  [32m✓[39m test/layout-derive.test.ts [2m([22m[2m10 tests[22m[2m)[22m[32m 138[2mms[22m[39m
2026-05-16T06:02:38.9649396Z apps/server test:  [32m✓[39m test/persistence.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 54[2mms[22m[39m
2026-05-16T06:02:39.1049008Z apps/client test: [90mstderr[2m | src/__test__/game-scene.test.ts[2m > [22m[2mscenes/GameScene[2m > [22m[2mtest 5: onRoomLayout calls verifyRoomLayout first; render skipped on false
2026-05-16T06:02:39.1052156Z apps/client test: [22m[39mroom_layout signature did not verify — rendering anyway (defense-in-depth; see 06.1-D40-SPIKE.md) mvp-lobby 000
2026-05-16T06:02:39.2021387Z apps/client test:  [32m✓[39m src/__test__/game-scene.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 230[2mms[22m[39m
2026-05-16T06:02:39.2344742Z apps/server test:  [32m✓[39m test/rate-limit.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 9[2mms[22m[39m
2026-05-16T06:02:39.5625905Z apps/server test:  [32m✓[39m test/room-key.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 29[2mms[22m[39m
2026-05-16T06:02:39.8913464Z apps/server test: {"level":40,"time":1778911359887,"pid":3341,"hostname":"runnervmrw5os","path":"/api/foo","msg":"staging_invite_rejected"}
2026-05-16T06:02:39.8993449Z apps/server test: {"level":40,"time":1778911359891,"pid":3341,"hostname":"runnervmrw5os","path":"/api/foo","msg":"staging_invite_rejected"}
2026-05-16T06:02:39.9013386Z apps/server test: {"level":40,"time":1778911359892,"pid":3341,"hostname":"runnervmrw5os","path":"/api/foo","msg":"staging_invite_rejected"}
2026-05-16T06:02:39.9026786Z apps/server test:  [32m✓[39m test/staging-invite.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 14[2mms[22m[39m
2026-05-16T06:02:40.3348309Z apps/client test:  [32m✓[39m src/__test__/nameplate-stability.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 24[2mms[22m[39m
2026-05-16T06:02:40.8538143Z apps/server test: {"level":30,"time":1778911360844,"pid":3352,"hostname":"runnervmrw5os","password":"[Redacted]","session_token":"[Redacted]","msg":"login"}
2026-05-16T06:02:40.8543721Z apps/server test:  [32m✓[39m test/otel-init.test.ts [2m([22m[2m4 tests[22m[2m)[22m[33m 729[2mms[22m[39m
2026-05-16T06:02:40.8565606Z apps/server test:      [33m[2m✓[22m[39m does not throw when OTEL_EXPORTER_OTLP_ENDPOINT is unset [33m 582[2mms[22m[39m
2026-05-16T06:02:41.6200653Z apps/client test:  [32m✓[39m src/__test__/sprite-state-machine.teleport-gate.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 96[2mms[22m[39m
2026-05-16T06:02:41.7568972Z apps/server test: [90mstdout[2m | test/run-migrations.test.ts[2m > [22m[2mrun-migrations.ts (Plan 12)[2m > [22m[2mScenario 1: fresh DB — migrate creates accounts table and records migration row
2026-05-16T06:02:41.7590759Z apps/server test: [22m[39m[run-migrations] opening /tmp/rebno-migrate-test-2lFuSi/rebno.db
2026-05-16T06:02:41.7613193Z apps/server test: [run-migrations] migrationsFolder=/home/runner/work/rebno/rebno/packages/db/migrations
2026-05-16T06:02:41.7620376Z apps/server test: [run-migrations] OK
2026-05-16T06:02:41.7794839Z apps/server test: [90mstdout[2m | test/run-migrations.test.ts[2m > [22m[2mrun-migrations.ts (Plan 12)[2m > [22m[2mScenario 2: pre-bootstrapped DB (Assumption A7) — reconcile seeds row before migrate runs
2026-05-16T06:02:41.7805016Z apps/server test: [22m[39m[run-migrations] opening /tmp/rebno-migrate-test-my3une/rebno.db
2026-05-16T06:02:41.7806779Z apps/server test: [run-migrations] migrationsFolder=/home/runner/work/rebno/rebno/packages/db/migrations
2026-05-16T06:02:41.7808747Z apps/server test: [run-migrations] reconciled __drizzle_migrations for pre-bootstrap DB (Assumption A7) — seeded 0001_baseline
2026-05-16T06:02:41.7810043Z apps/server test: [run-migrations] OK
2026-05-16T06:02:41.7884021Z apps/server test: [90mstdout[2m | test/run-migrations.test.ts[2m > [22m[2mrun-migrations.ts (Plan 12)[2m > [22m[2mScenario 3: idempotent second run — no error, no extra rows
2026-05-16T06:02:41.7891388Z apps/server test: [22m[39m[run-migrations] opening /tmp/rebno-migrate-test-nBmQDS/rebno.db
2026-05-16T06:02:41.7921706Z apps/server test: [run-migrations] migrationsFolder=/home/runner/work/rebno/rebno/packages/db/migrations
2026-05-16T06:02:41.7929761Z apps/server test: [run-migrations] OK
2026-05-16T06:02:41.7936070Z apps/server test: [90mstdout[2m | test/run-migrations.test.ts[2m > [22m[2mrun-migrations.ts (Plan 12)[2m > [22m[2mScenario 3: idempotent second run — no error, no extra rows
2026-05-16T06:02:41.7938947Z apps/server test: [22m[39m[run-migrations] opening /tmp/rebno-migrate-test-nBmQDS/rebno.db
2026-05-16T06:02:41.7952085Z apps/server test: [run-migrations] migrationsFolder=/home/runner/work/rebno/rebno/packages/db/migrations
2026-05-16T06:02:41.7976436Z apps/server test: [run-migrations] OK
2026-05-16T06:02:41.8023161Z apps/server test:  [32m✓[39m test/run-migrations.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 63[2mms[22m[39m
2026-05-16T06:02:42.0909808Z apps/server test:  [32m✓[39m test/log.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m 18[2mms[22m[39m
2026-05-16T06:02:42.3174169Z apps/server test:  [32m✓[39m test/admin-stubs.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 8[2mms[22m[39m
2026-05-16T06:02:42.6101491Z apps/server test:  [32m✓[39m test/legacy-login.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 31[2mms[22m[39m
2026-05-16T06:02:42.8104312Z apps/client test:  [32m✓[39m src/__test__/nameplate.test.ts [2m([22m[2m12 tests[22m[2m)[22m[32m 61[2mms[22m[39m
2026-05-16T06:02:42.8532029Z apps/server test:  [32m✓[39m test/health.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 6[2mms[22m[39m
2026-05-16T06:02:43.7193673Z apps/server test: [90mstdout[2m | test/tick-accumulator.test.ts
2026-05-16T06:02:43.7195802Z apps/server test: [22m[39m◇ injected env (50) from ../../../../../../../etc/environment // tip: ⌘ override existing { override: true }
2026-05-16T06:02:43.7213428Z apps/server test: ℹ️  optional .env file not found: .env.test, .env
2026-05-16T06:02:43.9309682Z apps/client test:  [32m✓[39m src/__test__/sprite-state-machine.test.ts [2m([22m[2m29 tests[22m[2m)[22m[32m 10[2mms[22m[39m
2026-05-16T06:02:44.4184049Z apps/server test:  [32m✓[39m test/tick-accumulator.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 7[2mms[22m[39m
2026-05-16T06:02:44.4423852Z apps/server test: [2m Test Files [22m [1m[32m12 passed[39m[22m[90m (12)[39m
2026-05-16T06:02:44.4463218Z apps/server test: [2m      Tests [22m [1m[32m71 passed[39m[22m[90m (71)[39m
2026-05-16T06:02:44.4504980Z apps/server test: [2m   Start at [22m 06:02:37
2026-05-16T06:02:44.4519086Z apps/server test: [2m   Duration [22m 7.23s[2m (transform 586ms, setup 0ms, import 3.64s, tests 1.11s, environment 2ms)[22m
2026-05-16T06:02:44.4905983Z apps/server test: Done
2026-05-16T06:02:44.8474228Z apps/client test:  [32m✓[39m src/__test__/login-scene.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 11[2mms[22m[39m
2026-05-16T06:02:45.6055617Z apps/client test:  [32m✓[39m src/__test__/reconnect.test.ts [2m([22m[2m16 tests[22m[2m)[22m[32m 78[2mms[22m[39m
2026-05-16T06:02:46.3388925Z apps/client test:  [32m✓[39m src/__test__/colyseus-client.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 11[2mms[22m[39m
2026-05-16T06:02:47.0496504Z apps/client test:  [32m✓[39m src/__test__/player-renderer.teleport.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 14[2mms[22m[39m
2026-05-16T06:02:47.7424161Z apps/client test:  [32m✓[39m src/__test__/player-renderer-spawn-delay.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m 19[2mms[22m[39m
2026-05-16T06:02:48.4257136Z apps/client test:  [32m✓[39m src/__test__/input-dispatcher.test.ts [2m([22m[2m12 tests[22m[2m)[22m[32m 16[2mms[22m[39m
2026-05-16T06:02:49.1714058Z apps/client test:  [32m✓[39m src/__test__/chat-hud.test.ts [2m([22m[2m9 tests[22m[2m)[22m[32m 84[2mms[22m[39m
2026-05-16T06:02:49.8753340Z apps/client test:  [32m✓[39m src/__test__/nameplate-color.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 32[2mms[22m[39m
2026-05-16T06:02:50.5527479Z apps/client test:  [32m✓[39m src/__test__/reconciler.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m 7[2mms[22m[39m
2026-05-16T06:02:51.2347222Z apps/client test:  [32m✓[39m src/__test__/room-renderer.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m 5[2mms[22m[39m
2026-05-16T06:02:51.9770324Z apps/client test:  [32m✓[39m src/__test__/force-reset-overlay.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 72[2mms[22m[39m
2026-05-16T06:02:52.7275269Z apps/client test:  [32m✓[39m src/__test__/esc-menu.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 75[2mms[22m[39m
2026-05-16T06:02:53.4207392Z apps/client test:  [32m✓[39m src/__test__/prediction.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m 5[2mms[22m[39m
2026-05-16T06:02:54.1604842Z apps/client test:  [32m✓[39m src/__test__/background-renderer.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 73[2mms[22m[39m
2026-05-16T06:02:54.8456557Z apps/client test:  [32m✓[39m src/__test__/extrapolation.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 5[2mms[22m[39m
2026-05-16T06:02:55.5165925Z apps/client test:  [32m✓[39m src/__test__/sprite-state-rate.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 4[2mms[22m[39m
2026-05-16T06:02:56.1867064Z apps/client test:  [32m✓[39m src/__test__/room-layout-verify.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 9[2mms[22m[39m
2026-05-16T06:02:56.8814991Z apps/client test:  [32m✓[39m src/__test__/input-dispatcher-shift.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 8[2mms[22m[39m
2026-05-16T06:02:57.5948756Z apps/client test:  [32m✓[39m src/__test__/boot-font-gate.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m 7[2mms[22m[39m
2026-05-16T06:02:58.2775994Z apps/client test:  [32m✓[39m src/__test__/legacy-origin.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 4[2mms[22m[39m
2026-05-16T06:02:58.9564429Z apps/client test:  [32m✓[39m src/__test__/auth-client.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 6[2mms[22m[39m
2026-05-16T06:02:59.6278440Z apps/client test:  [32m✓[39m src/__test__/room-collision-bottom-edge.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 5[2mms[22m[39m
2026-05-16T06:03:00.3148342Z apps/client test:  [32m✓[39m src/__test__/depth-set.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 3[2mms[22m[39m
2026-05-16T06:03:00.9866556Z apps/client test:  [32m✓[39m src/__test__/atlas-loader.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 8[2mms[22m[39m
2026-05-16T06:03:01.6864559Z apps/client test:  [32m✓[39m src/__test__/protocol-version-check.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 5[2mms[22m[39m
2026-05-16T06:03:02.4020992Z apps/client test:  [32m✓[39m src/__test__/env.test.ts [2m([22m[2m5 tests[22m[2m | [22m[33m4 skipped[39m[2m)[22m[32m 4[2mms[22m[39m
2026-05-16T06:03:02.4273740Z apps/client test: [2m Test Files [22m [1m[32m31 passed[39m[22m[90m (31)[39m
2026-05-16T06:03:02.4275382Z apps/client test: [2m      Tests [22m [1m[32m216 passed[39m[22m[2m | [22m[90m4 todo[39m[90m (220)[39m
2026-05-16T06:03:02.4283048Z apps/client test: [2m   Start at [22m 06:02:37
2026-05-16T06:03:02.4284613Z apps/client test: [2m   Duration [22m 25.18s[2m (transform 828ms, setup 64ms, collect 1.52s, tests 990ms, environment 14.80s, prepare 2.76s)[22m
2026-05-16T06:03:02.5645520Z apps/client test: Done
2026-05-16T06:03:02.5734281Z 
2026-05-16T06:03:02.5735091Z verify-phase-4: OK (12 steps green)
